package com.flyduck.vueshop.auth.admin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.SecureUtil;
import com.flyduck.vueshop.auth.admin.service.AdminLoginService;
import com.flyduck.vueshop.auth.admin.vo.AdminLoginReqVO;
import com.flyduck.vueshop.auth.admin.vo.AdminLoginRespVO;
import com.flyduck.vueshop.auth.admin.vo.AdminUserInfoRespVO;
import com.flyduck.vueshop.common.core.exception.BusinessException;
import com.flyduck.vueshop.common.core.utils.BeanUtils;
import com.flyduck.vueshop.system.constant.SysConstant;
import com.flyduck.vueshop.system.vo.RemoteMenuRespVO;
import com.flyduck.vueshop.system.vo.RemoteUserRespVO;
import com.flyduck.vueshop.system.feign.RemoteMenuFeignClient;
import com.flyduck.vueshop.system.feign.RemoteSysUserFeignClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * SysLoginServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2024-07-09
 */
@Service
public class AdminLoginServiceImpl implements AdminLoginService {

    @Resource
    private RemoteMenuFeignClient remoteMenuFeignClient;
    @Resource
    private RemoteSysUserFeignClient remoteSysUserFeignClient;

    @Override
    public AdminLoginRespVO login(AdminLoginReqVO adminLoginReqVO) {
        //校验用户名和密码
        RemoteUserRespVO remoteUserRespVO = remoteSysUserFeignClient.getUserByUsername(adminLoginReqVO.getUsername()).getData();
        if (remoteUserRespVO == null) {
            throw new BusinessException("用户名或者密码错误");
        }

        if (!remoteUserRespVO.getPassword().equals(SecureUtil.md5(adminLoginReqVO.getPassword()))) {
            throw new BusinessException("用户名或者密码错误");
        }

        //生成token
        StpUtil.login(remoteUserRespVO.getId());
        String tokenValue = StpUtil.getTokenValue();

        AdminLoginRespVO adminLoginRespVO = new AdminLoginRespVO();
        adminLoginRespVO.setToken(tokenValue);
        return adminLoginRespVO;
    }

    @Override
    public AdminUserInfoRespVO getUserInfo() {
        //1、用户信息
        long userId = StpUtil.getLoginIdAsLong();
        RemoteUserRespVO remoteUserRespVO = remoteSysUserFeignClient.getUserById(userId).getData();
        AdminUserInfoRespVO.SysUserInfoVO sysUserInfoVO = BeanUtils.toBean(remoteUserRespVO, AdminUserInfoRespVO.SysUserInfoVO.class);

        //2、菜单信息
        List<RemoteMenuRespVO> sysMenuList;
        if(userId == 1L){
            //管理员
            sysMenuList = remoteMenuFeignClient.getEnableMenuList().getData();
        }else {
            //非管理员
            sysMenuList = remoteMenuFeignClient.getEnableMenuListByUserId(userId).getData();
        }

        List<AdminUserInfoRespVO.SysMenuVO> sysMenuVOList = convertSysMenuToSysMenuVO(sysMenuList);
        List<AdminUserInfoRespVO.SysMenuVO> sysMenuVOTree = buildTreeMenu(sysMenuVOList);

        //3、权限信息
        List<String> permissionList = remoteMenuFeignClient.getPermissionListByUserId(userId).getData();

        AdminUserInfoRespVO adminUserInfoRespVO = new AdminUserInfoRespVO();
        adminUserInfoRespVO.setUserInfo(sysUserInfoVO);
        adminUserInfoRespVO.setMenuList(sysMenuVOTree);
        adminUserInfoRespVO.setPermissionList(permissionList);
        return adminUserInfoRespVO;
    }

    //构建树状结构
    private List<AdminUserInfoRespVO.SysMenuVO> buildTreeMenu(List<AdminUserInfoRespVO.SysMenuVO> sysMenuDTOList) {
        List<AdminUserInfoRespVO.SysMenuVO> sysMenuVOTree = new ArrayList<>();

        for (AdminUserInfoRespVO.SysMenuVO sysMenuVO : sysMenuDTOList) {
            //找出sysMenuDTO的子集，并赋值给children
            for (AdminUserInfoRespVO.SysMenuVO menuVO : sysMenuDTOList) {
                if(sysMenuVO.getId().equals(menuVO.getParentId())){
                    sysMenuVO.getChildren().add(menuVO);
                }

            }
            //提取目录作为顶级
            if (SysConstant.MenuType.DIRECTORY.getCode() == sysMenuVO.getType()) {
                sysMenuVOTree.add(sysMenuVO);
            }
        }
        return sysMenuVOTree;

    }

    private List<AdminUserInfoRespVO.SysMenuVO> convertSysMenuToSysMenuVO(List<RemoteMenuRespVO> remoteMenuRespVO) {
        return remoteMenuRespVO.stream()
                .map(sysMenu -> {
                    AdminUserInfoRespVO.SysMenuVO sysMenuVO = new AdminUserInfoRespVO.SysMenuVO();
                    sysMenuVO.setId(sysMenu.getId());
                    sysMenuVO.setParentId(sysMenu.getParentId());
                    sysMenuVO.setType(sysMenu.getType());
                    sysMenuVO.setTitle(sysMenu.getTitle());
                    sysMenuVO.setIcon(sysMenu.getIcon());
                    sysMenuVO.setPath(sysMenu.getPath());
                    sysMenuVO.setComponent(sysMenu.getComponent());
                    sysMenuVO.setName(sysMenu.getPerms());
                    return sysMenuVO;
                }).collect(Collectors.toList());
    }
}
